#ifndef AER_RESOURCEPROXY_HPP_
#define AER_RESOURCEPROXY_HPP_

#include "aerDefs.hpp"
#include <string>
#include <map>


namespace aer {


// todo : Singletonize it
template<typename T, typename I=std::string>
class ResourceProxy
{
  private:
    typedef std::map<T*, aer::I32> ProxyRefCountMap_t;
    typedef std::map<I, T*> ProxyFileMap_t;

    ProxyRefCountMap_t m_refCount;
    ProxyFileMap_t m_files;


  public:
    ~ResourceProxy() { destroy(); }
    
    void destroy()
    {
      typename ProxyFileMap_t::iterator it;
      
      for (it = m_files.begin(); it != m_files.end(); ++it) {
        AER_SAFE_DELETE( it->second );
      }      
    }

    T* get(const I &id)
    {
      T* obj = m_files[id];
      
      if (!obj) {
        obj = load(id);
        m_files[id] = obj;
        m_refCount[obj] = 0;
      }
      addRef(obj);
      
      return obj;
    }

    void release(T* obj) 
    {
      AER_ASSERT( m_refCount[obj] > 0 );
      
      if (0 == --m_refCount[obj]) {
        AER_SAFE_DELETE( obj );
      }
    }
    

  private:  
    void addRef(T* obj) 
    {
      AER_CHECK( obj != NULL );
      ++m_refCount[obj]; 
    }

    virtual T* load(const I&) { 
      return new T(); 
    }
};


} // namespace aer

#endif // AER_RESOURCE_RESOURCEPROXY_HPP_
